//
//  Utilities.m
//  ExhibitionHall
//
//  Created by 王洋 on 2019/6/11.
//  Copyright © 2019 王洋. All rights reserved.
//

#import "Utilities.h"
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>
#import <UIKit/UIFeedbackGenerator.h>

#define TT_kInitVector  @"ffGGtsdfzxCv5568"  //偏移量
#define TT_DESKey       @"gg356tt8g5h6j9jh"  //key

static NSMutableDictionary *soundIDs;

@interface Utilities ()

@end
@implementation Utilities

#pragma 震动反馈
+ (void)tapticEngineWork {
    
    if (@available(iOS 10.0, *)) {
        UIImpactFeedbackGenerator * impactLight = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
        [impactLight impactOccurred];
        
    } else {
        // Fallback on earlier versions
    }
}

#pragma mark 检查是否设置了网络代理
+ (BOOL)getProxyStatus {
    NSDictionary *proxySettings =  (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
    NSArray *proxies = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:@"http://www.baidu.com"]), (__bridge CFDictionaryRef _Nonnull)(proxySettings)));
    NSDictionary *settings = [proxies objectAtIndex:0];
    
//    NSLog(@"host=%@", [settings objectForKey:(NSString *)kCFProxyHostNameKey]);
//    NSLog(@"port=%@", [settings objectForKey:(NSString *)kCFProxyPortNumberKey]);
//    NSLog(@"type=%@", [settings objectForKey:(NSString *)kCFProxyTypeKey]);
    
    if ([[settings objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"]){
        //没有设置代理
        return NO;
    }else{
        //设置代理了
        return YES;
    }
}

#pragma mark 获取当前时间戳 秒为单位
+(NSTimeInterval )getCurrentTimestamp {
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;

    [formatter setDateStyle:NSDateFormatterMediumStyle];

    [formatter setTimeStyle:NSDateFormatterShortStyle];

    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制

    //设置时区,这个对于时间的处理有时很重要

    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];

    [formatter setTimeZone:timeZone];

    NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式

    NSTimeInterval timeSp = (double)([datenow timeIntervalSince1970]*1000);
    return timeSp;
}

// 服务器当前时间戳（精确到毫秒）
+ (NSTimeInterval)getCurrentServerTimestamp{
    // 最后保存的服务器时间戳
    NSTimeInterval lastSaveServerTimeStamp = [[NSUserDefaults standardUserDefaults] doubleForKey:@"kLastSaveServerTimeStamp"];
    // 最后保存服务器时间戳时的本地时间戳
    NSTimeInterval lastSaveLocalTimeStamp = [[NSUserDefaults standardUserDefaults] doubleForKey:@"kLastSaveLocalTimeStamp"];
    // 当前本地时间戳
    NSTimeInterval currentLocalTimeStamp = [[NSDate date] timeIntervalSince1970] * 1000;
    
    if (lastSaveLocalTimeStamp != 0 || lastSaveServerTimeStamp != 0) {
        return lastSaveServerTimeStamp + (currentLocalTimeStamp - lastSaveLocalTimeStamp);
    }else{
        // 如果没有获取到服务器时间，说明客户端还没开始用过，则视服务器时间与本地时间相同
        return  currentLocalTimeStamp;
    }
}

+ (NSTimeInterval )getTimestampWithDate:(NSDate *)date {
    NSTimeInterval timeSp = (double)([date timeIntervalSince1970]*1000);
    return timeSp;
}

////检查是否包含小数位
//+ (BOOL)isDoubleValueContainDecimal:(double)doubleValue {
//    if (doubleValue - floor(doubleValue) < 0.01) {
//        return NO;
//    } else {
//        return YES;
//    }
//}

+ (PPActivityProgress)checkActivityProgressWithStart:(NSTimeInterval)startStamp AndEnd:(NSTimeInterval)endStamp {
    NSTimeInterval currentTimeStamp = [Utilities getCurrentServerTimestamp];
    if (currentTimeStamp < startStamp) {
        return PPActivityProgress_waitStart;
    } else if (currentTimeStamp > startStamp && currentTimeStamp < endStamp) {
        return PPActivityProgress_processing;
    } else {
        return PPActivityProgress_over;
    }
}

#pragma mark ---- 将时间戳转换成时间
+ (NSString *)getTimeFromTimestamp:(NSTimeInterval)time {
    //将对象类型的时间转换为NSDate类型
    time = time/1000;
    NSDate * myDate=[NSDate dateWithTimeIntervalSince1970:time];
    //设置时间格式
    NSDateFormatter * formatter=[[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
    //将时间转换为字符串
    NSString *timeStr=[formatter stringFromDate:myDate];
    return timeStr;
}


+ (NSString *)getTodayAfterDateWithCount:(NSInteger)count {
    NSDate *currentDate = [NSDate date];
    
    NSDate *appointDate;    // 指定日期声明
    NSTimeInterval oneDay = 24 * 60 * 60;  // 一天一共有多少秒
    appointDate = [currentDate initWithTimeIntervalSinceNow: oneDay * count];
    
    NSDateFormatter * formatter=[[NSDateFormatter alloc] init];
//    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
//    [formatter setTimeZone:timeZone];

    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
    //将时间转换为字符串
    NSString *timeStr=[formatter stringFromDate:appointDate];
    return timeStr;
}

+ (NSString *)changeDoubleToString:(double)doubleValue{
    NSString *doubleStr = [NSString stringWithFormat:@"%f",doubleValue];
    NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithString:doubleStr];
    return dn.stringValue;
}

#pragma mark 检查是否是手机号
+ (BOOL)checkPhoneTel:(NSString *)phoneStr
{
    if (phoneStr && phoneStr.length) {
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",@"1+[3456789]+\\d{9}"];
        BOOL isMatch = [pred evaluateWithObject:phoneStr];
        return isMatch;
    }
    return NO;
}

#pragma mark 拨打电话
+ (void)callPhone:(NSString*)phoneNum {
    
    if(phoneNum.length==0){
        return;
    }
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"tel:%@",phoneNum]]];

//    if(phoneNum.length==0){
//        return;
//    }
//    NSString*callPhone = [NSString stringWithFormat:@"telprompt://%@",phoneNum];
//    dispatch_async(dispatch_get_global_queue(0,0),^{
//        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:callPhone]];
//    });
}

/**
 *  使用颜色生成指定尺寸图片
 */
+ (UIImage *)createImageWithColor:(UIColor *)color width:(CGFloat)width height:(CGFloat)height {
    CGRect rect = CGRectMake(0.0f, 0.0f, width, height);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}

#pragma mark DES 加密
+ (NSString *)encodeDesWithString:(NSString *)str{
    NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
    size_t plainTextBufferSize = [data length];
    const void *vplainText = (const void *)[data bytes];
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    bufferPtrSize = (plainTextBufferSize + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
    const void *vkey = (const void *) [TT_DESKey UTF8String];            //key
    const void *vinitVec = (const void *) [TT_kInitVector UTF8String];   //偏移量
    
    /*
     在JAVA中："DES/CBC/PKCS5Padding"  对应的  Object-C的是 kCCOptionPKCS7Padding.
               "DES/ECB/PKCS5Padding" 对应的   Object-C的是   kCCOptionPKCS7Padding | kCCOptionECBMod
     */
    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithmDES,
                       kCCOptionPKCS7Padding,  //对齐方式
                       vkey,
                       kCCKeySizeDES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes
                       );
    
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
    NSString *result = [myData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    return result;
    
}

#pragma mark DES 解密
+ (NSString *)decodeDesWithString:(NSString *)str{
    NSData *encryptData = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
    size_t plainTextBufferSize = [encryptData length];
    const void *vplainText = [encryptData bytes];
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    bufferPtrSize = (plainTextBufferSize + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
    const void *vkey = (const void *) [TT_DESKey UTF8String];
    const void *vinitVec = (const void *) [TT_kInitVector UTF8String];
    
    /*
     在JAVA中："DES/CBC/PKCS5Padding"  对应的  Object-C的是   kCCOptionPKCS7Padding.
              "DES/ECB/PKCS5Padding" 对应的   Object-C的是   kCCOptionPKCS7Padding | kCCOptionECBMod
     */
    ccStatus = CCCrypt(kCCDecrypt,
                       kCCAlgorithmDES,
                       kCCOptionPKCS7Padding,  //对齐方式
                       vkey,
                       kCCKeySizeDES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes
                       );
    NSString *result = [[NSString alloc]
                        initWithData:[NSData dataWithBytes:(const void *)bufferPtr
                                                    length:(NSUInteger)movedBytes]
                        encoding:NSUTF8StringEncoding];
    
    return result;
}

#pragma mark MD5
+ (NSString *)md5:(NSString *)string {
    const char *cStr = [string UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), digest);
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%2X", digest[i]];
    }
    return result;
}

#pragma mark NeteaseMd5 云信密码Md5
+ (NSString *)NeteaseMd5:(NSString *)string {
    const char *cstr = [string UTF8String];
    unsigned char result[16];
    CC_MD5(cstr, (CC_LONG)strlen(cstr), result);
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}


#pragma mark 计算string宽度
+ (float)getStringWidthWithString:(NSString *)value fontSize:(float)fontSize andHeight:(float)height{

    CGSize size = [value boundingRectWithSize:CGSizeMake(MAXFLOAT, 0.0) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0]} context:nil].size;

    return size.width;
}

+ (NSMutableDictionary *)getParams:(NSString *)str
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    NSArray *item = [str componentsSeparatedByString:@"&"];
    for (NSString *param in item) {
        NSArray *paramArray = [param componentsSeparatedByString:@"="];
        
        if (paramArray.count < 2) {
            return @{}.mutableCopy;
        } else if (paramArray.count == 2) {
            [dict setObject:[NSString stringWithFormat:@"%@", paramArray[1]] forKey:paramArray[0]];
        } else if (paramArray.count > 2) {
            //有可能是url带参
            NSArray *escArray = [param componentsSeparatedByString:@"="];
            NSString *escStr = [NSString stringWithFormat:@"%@%@",escArray[0],@"="];
            NSString *url =  [param stringByReplacingOccurrencesOfString:escStr withString:@""];
            [dict setObject:[NSString stringWithFormat:@"%@", url] forKey:escArray[0]];
        }
    }
    
    return dict;
}

#pragma mark dic转jsonString
+ (NSString *)stringWithDictionary:(NSDictionary *)dict {
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
    NSString *jsonString;
    if (!jsonData) {
        NSLog(@"%@",error);
    }else{
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    NSRange range = {0,jsonString.length};
    //去掉字符串中的空格
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    NSRange range2 = {0,mutStr.length};
    //去掉字符串中的换行符
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    return mutStr;
}


#pragma mark string转dic
+ (NSDictionary *)dictionaryWithString:(NSString *)jsonString
{
    if (jsonString == nil) {return nil;}
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    if(err){return nil;}
    return dic;
}

#pragma mark json转dic
+ (NSDictionary *)dictionaryWithJsonString:(id)jsonD{
    if (jsonD == nil) {
        return nil;
    }
    
    NSData *jsonData = nil;
    if ([jsonD isKindOfClass:[NSString class]]){
        jsonData = [jsonD dataUsingEncoding:NSUTF8StringEncoding];
    }else if ([jsonD isKindOfClass:[NSData class]]){
        jsonData = jsonD;
    }else if([jsonD isKindOfClass:[NSDictionary class]]){
        NSDictionary *nonullDict = [self nullDic:jsonD];
        return nonullDict;
    }
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    if(err) {
        return nil;
    }
    dic = [self nullDic:dic];
    return dic;
}

//类型识别:将所有的NSNull类型转化成@""
+(id)changeType:(id)myObj
{
    if ([myObj isKindOfClass:[NSDictionary class]])
    {
        return [self nullDic:myObj];
    }
    else if([myObj isKindOfClass:[NSArray class]])
    {
        return [self nullArr:myObj];
    }
    else if([myObj isKindOfClass:[NSString class]])
    {
        return [self stringToString:myObj];
    }
    else if([myObj isKindOfClass:[NSNull class]])
    {
        return [self nullToString];
    }
    else
    {
        return myObj;
    }
}

//将NSDictionary中的Null类型的项目转化成@""
+(NSDictionary *)nullDic:(NSDictionary *)myDic
{
    if ([myDic isKindOfClass:[NSDictionary class]]) {
        NSArray *keyArr = [myDic allKeys];
        NSMutableDictionary *resDic = [[NSMutableDictionary alloc]init];
        for (int i = 0; i < keyArr.count; i ++)
        {
            id obj = [myDic objectForKey:keyArr[i]];
            obj = [self changeType:obj];
            [resDic setObject:obj forKey:keyArr[i]];
        }
        return resDic;
    }else {
        return @{};
    }
    
}
//将NSDictionary中的Null类型的项目转化成@""
+(NSArray *)nullArr:(NSArray *)myArr
{
    if ([myArr isKindOfClass:[NSArray class]]) {
        NSMutableArray *resArr = [[NSMutableArray alloc] init];
        for (int i = 0; i < myArr.count; i ++)
        {
            id obj = myArr[i];
            obj = [self changeType:obj];
            [resArr addObject:obj];
        }
        return resArr;
    }else {
        return @[];
    }
    
}
//将NSString类型的原路返回
//过滤掉诡异的"null"和"(null)"字符串
+(NSString *)stringToString:(NSString *)string
{
    if ([string isEqualToString:@"null"] || [string isEqualToString:@"(null)"]) {
        return @"";
    }else{
        return string;
    }
}
//将Null类型的项目转化成@""
+(NSString *)nullToString
{
    return @"";
}

#pragma mark 音频文件播放
+ (void)playSoundWithFileName:(NSString *)name fileType:(NSString *)type {
        //name是音频文件的名称
        NSString *urlString = [NSString stringWithFormat:@"%@",[[NSBundle mainBundle] pathForResource:name ofType:type]];
        SystemSoundID soundID = 0;

        NSURL *url = [NSURL URLWithString:urlString];
        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)url, &soundID);

        AudioServicesPlaySystemSound(soundID);
    }


+ (NSString *) utf8ToUnicode:(NSString *)string{
    
    NSUInteger length = [string length];
    NSMutableString *str = [NSMutableString stringWithCapacity:0];
    for (int i = 0;i < length; i++){
        NSMutableString *s = [NSMutableString stringWithCapacity:0];
        unichar _char = [string characterAtIndex:i];
        // 判断是否为英文和数字
        if (_char <= '9' && _char >='0'){
            [s appendFormat:@"%@",[string substringWithRange:NSMakeRange(i,1)]];
        }else if(_char >='a' && _char <= 'z'){
            [s appendFormat:@"%@",[string substringWithRange:NSMakeRange(i,1)]];
        }else if(_char >='A' && _char <= 'Z')
        {
            [s appendFormat:@"%@",[string substringWithRange:NSMakeRange(i,1)]];
        }else{
            // 中文和字符
            [s appendFormat:@"\\u%x",[string characterAtIndex:i]];
            // 不足位数补0 否则解码不成功
            if(s.length == 4) {
                [s insertString:@"00" atIndex:2];
            } else if (s.length == 5) {
                [s insertString:@"0" atIndex:2];
            }
        }
        [str appendFormat:@"%@", s];
    }
    return str;
}

+ (BOOL)checkOnceADayWithKey:(NSString *)key {
    
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSDate *now = [NSDate date];
    NSDate *agoDate = [userDefault objectForKey:key];
        
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
        
    NSString *ageDateString = [dateFormatter stringFromDate:agoDate];
    NSString *nowDateString = [dateFormatter stringFromDate:now];
        
    if ([ageDateString isEqualToString:nowDateString]) {
        
        return NO;
     }else{
         
         [userDefault setValue:now forKey:key];
         [userDefault synchronize];
         return YES;
     }
}

@end
